/*
    This file is part of the substandard lisp implementation of Standard Lisp
    Copyright (C) 2011 Nicky Nickell

    substandard lisp is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

function std_equal(a, env) {
  var u = a[0];
  var v = a[1];

  if (std_eqn([u, v], env) == T) {
    return T;
  }

  switch (u.type) {
  case TYPE_STRING:
    return (u.value == v.value) ? T : NIL;
  case TYPE_VECTOR:
    if (u.value.length != v.value.length) {
      return NIL;
    } else {
      for (var i = 0; i < u.value.length; i++) {
        if (std_equal([u.value[i], v.value[i]], env) == NIL) {
          return NIL;
        }
      }
      return T;
    }
  case TYPE_PAIR:
    if (v.type == TYPE_PAIR) {
      if (std_equal([u.car, v.car], env) == NIL) {
        return NIL;
      } else {
        return std_equal([u.cdr, v.cdr], env);
      }
    } else {
      return NIL;
    }
  }

  return NIL;
}

/*---
name: equal
arity: 2
rest: false
ftype: FTYPE_EXPR

argument-types:
  - CLASS_ANY
  - CLASS_ANY

doc: |
  explaining what equal is / how it is used!

tests: |
  (equal T T) -> T
  (equal T NIL) -> NIL
  (equal '(1 2 3) '(1 2 3)) -> T
  (equal '(1 2 3) '(4 5 6)) -> NIL
  (equal (cons 1 2) (cons 1 2)) -> T
  (equal (cons 1 2) (cons 3 4)) -> NIL
  (equal (mkvect 2) (mkvect 2)) -> T
  (equal (mkvect 2) (mkvect 3)) -> NIL
  (equal "foo" "foo") -> T
  (equal "foo" "bar") -> NIL
  (equal #'equal #'equal) -> T
  (equal #'equal #'eq) -> NIL
...*/
